package com.enjoy.geekbang.prototype2;

import java.util.HashMap;
import java.util.List;

/**
 * @author xuyanqing
 * @description 原型模式
 * 钱拷贝优缺点
 * （1）优点：基本属性均实现克隆。
 * （2）缺点：引用类型未实现克隆。
 * 深拷贝优缺点
 * （1）优点：如果原始对象变化，其克隆对象也会发生相应变化，无需修改代码
 * （2）缺点：实现深拷贝可能需要比较复杂的代码；对已有拷贝类进行改造时需要修改器源代码，违背了OCP开闭原则
 * @date 2025-10-22 11:51
 * @creed where there is a will,there is a way. yx
 */

public class Demo {

    private HashMap<String, SearchWord> currentKeywords = new HashMap<>();
    private long lastUpdateTime = -1;

    public void refresh1() {
        // 原型模式就这么简单，拷贝已有对象的数据，更新少量差值
        // 利用了 Java 中的 clone() 语法来复制一个对象
        // 浅拷贝
        HashMap<String, SearchWord> newKeywords = (HashMap<String, SearchWord>) currentKeywords.clone();

        // 从数据库中取出更新时间>lastUpdateTime的数据，放入到newKeywords中
        List<SearchWord> toBeUpdatedSearchWords = getSearchWords(lastUpdateTime);
        long maxNewUpdatedTime = lastUpdateTime;
        assert toBeUpdatedSearchWords != null;
        for (SearchWord searchWord : toBeUpdatedSearchWords) {
            if (searchWord.getLastUpdateTime() > maxNewUpdatedTime) {
                maxNewUpdatedTime = searchWord.getLastUpdateTime();
            }
            if (newKeywords.containsKey(searchWord.getKeyword())) {
                SearchWord oldSearchWord = newKeywords.get(searchWord.getKeyword());
                oldSearchWord.setCount(searchWord.getCount());
                oldSearchWord.setLastUpdateTime(searchWord.getLastUpdateTime());
            } else {
                newKeywords.put(searchWord.getKeyword(), searchWord);
            }
        }
        lastUpdateTime = maxNewUpdatedTime;
        currentKeywords = newKeywords;
    }

    /**
     * 推荐
     */
    public void refresh2() {
        // 原型模式就这么简单，拷贝已有对象，更新少量差值
        // 利用了 Java 中的 clone() 语法来复制一个对象
        // 深拷贝
        HashMap<String, SearchWord> newKeywords = (HashMap<String, SearchWord>) currentKeywords.clone();
        List<SearchWord> toBeUpdatedSearchWords = getSearchWords(lastUpdateTime);
        long maxNewUpdatedTime = lastUpdateTime;
        assert toBeUpdatedSearchWords != null;
        for (SearchWord searchWord : toBeUpdatedSearchWords) {
            if ( searchWord.getLastUpdateTime() > maxNewUpdatedTime){
                maxNewUpdatedTime = searchWord.getLastUpdateTime();
            }
            if (newKeywords.containsKey(searchWord.getKeyword())) {
                newKeywords.remove(searchWord.getKeyword());
            }
            newKeywords.put(searchWord.getKeyword(), searchWord);
        }
        lastUpdateTime = maxNewUpdatedTime;
        currentKeywords = newKeywords;
        System.out.println("更新时间：" + lastUpdateTime);
    }

    private List<SearchWord> getSearchWords(long lastUpdateTime) {
        // TODO: 从数据库中取出更新时间>lastUpdateTime的数据
        return null;
    }
}
